package com.banmoon.interpreter;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class Context {

    private String expStr;

    private Expression expression;

    /**
     * 构造函数，输入表达式，对表达式进行分析，得出对应的解释器
     * @param expStr
     */
    public Context(String expStr) {
        // 创建栈，一会分析表达式
        Stack<Expression> stack = new Stack<>();
        // 分析表达式
        char[] charArr = expStr.toCharArray();

        Expression left = null;
        Expression right = null;
        for (int i = 0; i < charArr.length; i++) {
            switch (charArr[i]){
                case '+':
                    left = stack.pop();
                    right = new ValueExpression(StrUtil.toString(charArr[++i]));
                    stack.push(new AddExpression(left, right));
                    break;
                case '-':
                    left = stack.pop();
                    right = new ValueExpression(StrUtil.toString(charArr[++i]));
                    stack.push(new SubtractExpression(left, right));
                    break;
                default:
                    stack.push(new ValueExpression(StrUtil.toString(charArr[i])));
                    break;
            }
        }
        this.expression = stack.pop();
        this.expStr = expStr;
    }

    /**
     * 进行计算
     * @param map
     * @return
     */
    public int count(Map<String, Integer> map){
        int result = this.expression.interpreter(map);
        System.out.println(expStr + "=" + result);
        return result;
    }

    /**
     * 快速创建表达式上下文
     * @return
     * @throws IOException
     */
    public static Context createContext() throws IOException {
        System.out.print("请输入表达式：");
        String expStr = new BufferedReader(new InputStreamReader(System.in)).readLine();
        return new Context(expStr);
    }

    /**
     * 根据当前的表单事，提供输入具体值
     * @return
     * @throws IOException
     */
    public Map<String, Integer> setValMap() throws IOException {
        HashMap<String, Integer> map = new HashMap<>();
        for (char ch : expStr.toCharArray()) {
            if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z')){
                System.out.print(StrUtil.format("请输入{}的值：", ch));
                String number = new BufferedReader(new InputStreamReader(System.in)).readLine();
                map.put(StrUtil.toString(ch), Convert.toInt(number, 0));
            }
        }
        return map;
    }

}
